package org.jeecg.modules.gis.typeHandler.dm;

import dm.jdbc.driver.DmdbBlob;
import dm.jdbc.driver.DmdbConnection;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.jeecg.modules.gis.util.DmUtil;
import org.jeecg.modules.gis.util.GisDbUtil;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.sql.*;

/**
 * description: 网格工具 [描述信息]
 *
 * @author zhoumingyang [作者]
 * @version 1.0.0 [版本信息]
 * @date 2022/05/26 16:22:57 [时间，这里是年/月/日 时:分:秒的格式]
 */

public class DmGeoPolygonTypeHandler extends BaseTypeHandler<Polygon> {

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Polygon polygon, JdbcType jdbcType) throws SQLException {
        try {
            Connection conn = preparedStatement.getConnection();
            DmdbConnection dmdbConn = DmUtil.getDmdbConnection(conn);
            Struct struct = convertToBytes(polygon, dmdbConn);
            preparedStatement.setObject(i, struct);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Polygon getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Struct struct = (Struct) rs.getObject(columnName);
        return convertToGeo(struct);

    }


    @Override
    public Polygon getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
        Struct struct = (Struct) resultSet.getObject(columnIndex);
        return convertToGeo(struct);
    }

    @Override
    public Polygon getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
        Struct struct = (Struct) callableStatement.getObject(columnIndex);
        return convertToGeo(struct);
    }

    /**
     * bytes转Geo对象
     *
     * @param struct
     * @return
     */
    private Polygon convertToGeo(Struct struct) {
        if (struct == null) {
            return null;
        }
        try {
            Object[] attrs = struct.getAttributes(); //获取结构体中的成员
            int srid = (Integer) attrs[0];    //获取SRID属性信息
            Blob blob = (Blob) attrs[1];        //获取GEO_WKB属性信息
            int type = (Integer) attrs[2];    //获取GEO_TYPEID属性信息
            byte[] geomBytes = blob.getBytes(1, (int) blob.length());
            Geometry geometry = new WKBReader().read(geomBytes);
            return (Polygon) geometry;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * geo转bytes
     *
     * @param geometry
     * @return
     * @throws IOException
     */
    private Struct convertToBytes(Geometry geometry, Connection conn) throws IOException, SQLException {
        byte[] geometryBytes = new WKBWriter().write(geometry);

        //设置SRID为4326
        Object[] attrs = new Object[3];

        attrs[0] = 4326;

        attrs[1] = DmdbBlob.newInstanceOfLocal(geometryBytes, (DmdbConnection) conn);
        ;
        attrs[2] = 3;
        Struct struct = conn.createStruct("ST_POLYGON", attrs);
        return struct;
    }
}
